<template>
  <div class="comment">
    <!--van-list：实现瀑布加载效果-->
    <van-list v-model="loading" :finished="finished" finished-text="没有更多了" @load="onLoad">
      <!--注意：com_id是数组格式信息，需要调用toString()变为字符串，否则vue会报错-->
      <van-cell v-for="item in commentList" :key="item.com_id.toString()">
        <!-- slot:插槽的使用，后面的属性值，都是van-cell组件提供的
               icon：自定义左侧图标
               title：自定义左侧标题
               default：自定义右侧内容
               label：自定义标题下方描述
        -->
        <!-- 作者头像 -->
        <div slot="icon">
          <img class="avatar" :src="item.aut_photo" alt />
        </div>
        <!-- 作者名称 -->
        <div slot="title">
          <span>{{item.aut_name}}</span>
        </div>
        <!-- 点赞 -->
        <div slot="default">
          <van-button
            icon="like-o"
            size="mini"
            :type="item.is_liking?'danger':'default'"
            plain
          >&nbsp;{{item.like_count}}</van-button>
        </div>
        <!-- 评论内容和时间 -->
        <div slot="label">
          <p>{{item.content}}</p>
          <p>
            <span>{{item.pubdate | formatTime}}</span>
            ·
            <span
              @click="openReply(item.com_id.toString())"
            >{{item.reply_count}}&nbsp;回复</span>
          </p>
        </div>
      </van-cell>
    </van-list>

    <!-- 回复列表展示-弹出层/瀑布 -->
    <van-popup v-model="showReply" position="bottom" :style="{ height: '80%' }" round>
      <!-- 瀑布加载效果 -->
      <!-- 名称为onLoadReply，避免与评论的onLoad有冲突 -->
      <van-list
        v-model="reply.loading"
        :finished="reply.finished"
        finished-text="没有更多了"
        @load="onLoadReply"
      >
        <van-cell v-for="item in replyList" :key="item.com_id.toString()">
          <!-- 作者头像 -->
          <div slot="icon">
            <img class="avatar" :src="item.aut_photo" alt />
          </div>
          <!-- 作者名称 -->
          <div slot="title">
            <span>{{item.aut_name}}</span>
          </div>
          <!-- 回复内容和时间 -->
          <div slot="label">
            <p v-html="item.content"></p>
            <p>
              <span>{{item.pubdate | formatTime}}</span>
            </p>
          </div>
        </van-cell>
      </van-list>
    </van-popup>

    <!-- 添加评论或回复的小构件 -->
    <div class="reply-container van-hairline--top">
      <van-field v-model.trim="contentCorR" placeholder="写评论或回复...">
        <!-- van-loading:设置加载图标，与提交进行配置使用
        slot="button"命名插槽，表明要给van-field的指定位置填充内容(右侧)-->
        <van-loading v-if="submitting" slot="button" type="spinner" size="16px"></van-loading>
        <span class="submit" v-else slot="button" @click="add">提交</span>
      </van-field>
    </div>
  </div>
</template>

<script type="text/javascript">
// 导入评论回复【api】
// 导入添加评论或添加回复的api函数
import { apiReplyList, apiAddCorR } from '@/api/reply.js'

// 导入获取文章评论的api函数
import { apiCommentList } from '@/api/comment.js'

export default {
  name: 'com-comment',
  data () {
    return {
      // 回复相关---------------------------------------------
      nowComID: '', // 被单击激活的评论
      lastID: null, // 分页标志(null、前一次返回的last_id)
      replyList: [], // 回复列表
      showReply: false, // 回复弹出层是否展示，false为不显示
      // 回复瀑布相关，通过reply成员包围，使得与外部的评论瀑布成员没有冲突
      reply: {
        list: [],
        loading: false,
        finished: false
      },

      // 评论相关----------------------------------------------
      commentList: [], // 评论列表数据
      offset: null, // 评论的分页标志,数据偏移量，因为offset不会再模板中作展示，所以可以设为null

      //   list: [],
      loading: false,
      finished: false,

      // 添加评论或回复成员-------------------------------------------
      contentCorR: '', // 评论或回复的内容
      submitting: false // 是否正在提交
    }
  },
  methods: {
    // 添加 评论 或 回复----------------------------------------------
    async add () {
      // 没有输入内容,则不作任何处理，停止代码执行
      if (!this.contentCorR) return false

      // 开启提交中
      this.submitting = true

      // 延迟1秒
      await this.$sleep(1000)

      // 通过showReply的boolean值，可以知道当前是评论 和 回复
      if (this.showReply) {
        // 添加回复逻辑
        const result = await apiAddCorR({
          target: this.nowComID, // 当前评论的id
          content: this.contentCorR,
          artID: this.$route.params.aid // 当前文章的id
        })
        // console.log(result)
        // 新添加的完整记录，会被服务器端返回，字段名称是：new_obj
        // 现在要把新添加的回复要放到页面做显示，就是要给当前的回复列表做头部追加
        this.replyList.unshift(result.new_obj)

        // 找到当前在做回复的评论项目，对回复的数量进行累加操作
        // 获得当前评论的下标信息
        const index = this.commentList.findIndex(item => {
          // item:代表评论数组中的每个元素
          // 条件是：this.com_id.toString()===this.nowComID
          return item.com_id.toString() === this.nowComID
        })

        // 通过index找到当前回复的评论目标，对其做回复数量的增加(reply_count++)
        this.commentList[index].reply_count++
      } else {
        // 添加评论逻辑
        const result = await apiAddCorR({
          target: this.$route.params.aid, // 当前文章的id
          content: this.contentCorR
        })
        // console.log(result)
        // 新添加的完整记录，会被服务器端返回，字段名称是：new_obj
        // 现在要把新添加的评论要放到页面做显示，就是要给当前的评论列表做头部追加
        this.commentList.unshift(result.new_obj)
      }

      // 添加完之后，清除输入框
      this.contentCorR = ''
      // 结束“提交中”的动画
      this.submitting = false
    },

    // 单击回复标志，展示回复弹出层逻辑-----------------------------------------
    // 参数commentID：被激活的评论id
    openReply (commentID) {
      this.nowComID = commentID
      this.showReply = true // 展开弹出层

      this.replyList = [] // 旧的回复数据清除
      this.lastID = null // 恢复分页偏移量
      this.reply.finished = false // 激活瀑布
    },

    // 回复瀑布加载--------------------------------------------
    async onLoadReply () {
      // 加载的延迟效果
      await this.$sleep(1000)

      // 获取回复数据
      const result = await apiReplyList({
        commentID: this.nowComID,
        lastID: this.lastID
      })

      // 加载完成，停止动画
      this.reply.loading = false

      // 若没有获取到数据
      if (result.results.length === 0) {
        this.reply.finished = true
        return false
      }

      // 若获取到数据，则给replyList做追加
      this.replyList.push(...result.results)
      // 接收分页标志的last_id信息
      this.lastID = result.last_id

      // 异步更新数据
      //   // setTimeout 仅做示例，真实场景中一般为 ajax 请求
      //   setTimeout(() => {
      //     for (let i = 0; i < 10; i++) {
      //       this.reply.list.push(this.reply.list.length + 1)
      //     }

      //     // 加载状态结束
      //     this.reply.loading = false

      //     // 数据全部加载完成
      //     if (this.reply.list.length >= 40) {
      //       this.reply.finished = true
      //     }
      //   }, 1000)
    },

    // 评论瀑布加载--------------------------------------------
    async onLoad () {
      // 延迟效果
      await this.$sleep(1000)

      // 根据文章id获得评论列表
      const comments = await apiCommentList({
        articleID: this.$route.params.aid,
        offset: this.offset
      })

      // 瀑布动画消失
      this.loading = false

      // 判断是否有获得到评论数据
      if (!comments.results.length) {
        // 停止瀑布
        this.finished = true
        return false // 停止后续代码执行
      }

      // 有数据，给追加到commentList成员里边
      this.commentList.push(...comments.results)

      // 获取评论的分页数据(last_id)
      this.offset = comments.last_id

      // 获取

      // 异步更新数据
      //   setTimeout(() => {
      //     for (let i = 0; i < 5; i++) {
      //       this.list.push(this.list.length + 1)
      //     }
      //     // 加载状态结束
      //     this.loading = false

      //     // 数据全部加载完成
      //     if (this.list.length >= 10) {
      //       this.finished = true
      //     }
      //   }, 500)
    }
  }
}
</script>

<style scoped lang="less" >
.comment {
  margin-top: 15px;
  .avatar {
    width: 50px;
    height: 50px;
    border-radius: 100%;
    margin-right: 10px;
  }
  /deep/ .van-cell__title {
    .van-cell__label {
      width: 400px;
    }
  }
}

// 添加评论或回复构件
.reply-container {
  position: fixed;
  left: 0;
  bottom: 0;
  height: 88px;
  width: 100%;
  background: #f5f5f5;
  z-index: 9999;
  .submit {
    font-size: 24px;
    color: #3296fa;
  }
}
</style>
